package com.otod.sys.auth.service;

import com.otod.commons.auth.SessionUserHolder;
import com.otod.commons.utils.Collections3;
import com.otod.commons.utils.Encodes;
import com.otod.commons.utils.SpringContextHolder;
import com.otod.pm.constants.PmConstant;
import com.otod.sys.emp.service.IEmpService;
import com.otod.sys.emp.service.impl.EmpServiceImpl;
import com.otod.sys.role.service.IRoleService;
import com.otod.sys.role.service.impl.RoleServiceImpl;
import com.otod.sys.vo.AuapREmpOrgRoleVo;
import com.otod.sys.vo.AuapTEmpVo;
import com.otod.sys.vo.AuapTRoleVo;

import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

import java.io.Serializable;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 系统权限统一控制类
 * Created by super  on 14-5-8.
 */
@Service
@DependsOn({"empMapper", "empOrgRoleMapper"})
public class ShiroDbRealm extends AuthorizingRealm {

    public static final String HASH_ALGORITHM = "SHA-1";
    public static final int HASH_INTERATIONS = 1024;

    public static IEmpService empService;
    
    public static IRoleService roleService;
    
    

    /**
     * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    /**
     * 认证回调函数, 登录时调用
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        //验证密码
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("empNo", token.getUsername());
        map.put("statusFlag", "90050002");
        AuapTEmpVo auapTEmpVo = getEmpService().getByEmpNoAndStatus(map);
        if (auapTEmpVo!=null) {
            byte[] salt = Encodes.decodeHex(auapTEmpVo.getPwd().substring(0, 16));
            return new SimpleAuthenticationInfo(new Principal(auapTEmpVo), auapTEmpVo.getPwd().substring(16), ByteSource.Util.bytes(salt), getName());
        } else {
            return null;
        }

    }

    /**
     * 设定密码校验的Hash算法与迭代次数
     */
    @PostConstruct
    public void initCredentialsMatcher() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(HASH_ALGORITHM);
        matcher.setHashIterations(HASH_INTERATIONS);
        setCredentialsMatcher(matcher);
    }

    public static IEmpService getEmpService() {
        if (empService == null) {
            empService = SpringContextHolder.getBean(EmpServiceImpl.class);
        }
        return empService;
    }
    
    public static IRoleService getRoleService() {
    	if (roleService == null) {
    		roleService = SpringContextHolder.getBean(RoleServiceImpl.class);
    	}
    	return roleService;
    }

    /**
     * 授权用户信息
     */
    public static class Principal implements Serializable {

        private static final long serialVersionUID = 1L;

        private String uuid;
        private String empNo;
        private String empName;
        private String ipAddr;
        private String roleNo;
        private String roleName;
        private String roleId;
        private SessionUserHolder user; 

        public Principal(AuapTEmpVo emp) {
            this.uuid = emp.getUuid();
            this.empNo = emp.getEmpNo();
            this.empName = emp.getEmpName();
            this.ipAddr = getIpAddr();
            
            user = new SessionUserHolder();
            user.setUserNo(empNo);
            user.setUserName(empName);
            user.setLoginIp(ipAddr);
            
            AuapTRoleVo roleVo = null;
           List<AuapREmpOrgRoleVo> rolelist = getEmpService().queryForListEmpNo(emp.getEmpNo());
           for (AuapREmpOrgRoleVo auapREmpOrgRoleVo : rolelist) {
			roleVo = getRoleService().getById(auapREmpOrgRoleVo.getRoleId());
				user.setRoleNo(roleVo.getRoleNo());
				this.roleNo = roleVo.getRoleNo();
           }
           
           
           
           
           
           
            
            
            
        }

        
        public SessionUserHolder getUser() {
			return user;
		}
        /**
         * 得到本机的ip地址
         * @return
         */
        public String getIpAddr(){
        	 String ip="";
	    	 try{
	            // 获取IP地址
	             ip = InetAddress.getLocalHost().getHostAddress();
	        }catch (UnknownHostException e){
	            e.printStackTrace();
	        }
	    	 return ip;
        }
        
		public String getUuid() {
            return uuid;
        }

        public String getEmpNo() {
            return empNo;
        }

        public String getEmpName() {
            return empName;
        }
        
        public String getRoleNo(){
        	return roleNo;
        }
        
        
    }

}
